package com.jinwei.qunguanjia.system.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.jinwei.qunguanjia.system.dao.SysConfigDAO;
import com.jinwei.qunguanjia.system.dto.SysConfigDTO;
import com.jinwei.qunguanjia.system.po.SysConfigPO;
import com.jinwei.qunguanjia.common.constant.CacheConstants;
import com.jinwei.qunguanjia.common.constant.UserConstants;
import com.jinwei.qunguanjia.common.core.domain.model.Condition;
import com.jinwei.qunguanjia.common.core.page.PageDataInfo;
import com.jinwei.qunguanjia.common.core.redis.RedisCache;
import com.jinwei.qunguanjia.common.core.text.Convert;
import com.jinwei.qunguanjia.common.utils.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.Collection;
import java.util.List;

import static com.jinwei.qunguanjia.common.utils.DictUtils.getCacheKey;

/**
 * 参数配置 服务层实现类
 * @author yuanzs
 */
@Service("sysConfigService")
public class SysConfigServiceImpl implements SysConfigService {

    @Resource
    private SysConfigDAO sysConfigDAO;

    @Resource
    private RedisCache redisCache;

    /**
     * 项目启动时，初始化参数到缓存
     */
    //@PostConstruct
    public void init() throws IllegalAccessException {
        loadingConfigCache();
    }

    @Override
    public void save(SysConfigDTO sysConfigDTO) {
        SysConfigPO sysConfigPO = new SysConfigPO();
        BeanUtils.copyProperties(sysConfigDTO, sysConfigPO);
        sysConfigPO.setConfigId(IdUtils.getWorkerId());
        int row = sysConfigDAO.insert(sysConfigPO);
        if (row > 0) {
            redisCache.setCacheObject(getCacheKey(sysConfigDTO.getConfigKey()), sysConfigDTO.getConfigValue());
        }
    }

    @Override
    public void remove(List<String> ids) {
        LambdaQueryWrapper<SysConfigPO> lambdaWrapper = new LambdaQueryWrapper<>();
        lambdaWrapper.in(SysConfigPO::getConfigId, ids);
        sysConfigDAO.delete(lambdaWrapper);
    }

    @Override
    public void update(SysConfigDTO sysConfigDTO) {
        SysConfigPO sysConfigPO = new SysConfigPO();
        BeanUtils.copyProperties(sysConfigDTO, sysConfigPO);
        int row = sysConfigDAO.updateById(sysConfigPO);
        if (row > 0) {
            redisCache.setCacheObject(getCacheKey(sysConfigDTO.getConfigKey()), sysConfigDTO.getConfigValue());
        }
    }

    @Override
    public SysConfigDTO get(String id) {
        SysConfigPO sysConfigPO = sysConfigDAO.selectById(id);
        SysConfigDTO sysConfigDTO = new SysConfigDTO();
        BeanUtils.copyProperties(sysConfigPO, sysConfigDTO);
        return sysConfigDTO;
    }

    @Override
    public SysConfigDTO get(SysConfigDTO sysConfigDTO) throws IllegalAccessException {
        // 添加查询条件
        List<Condition> conditionList = ConditionUtils.add(sysConfigDTO);
        // 拼接查询条件
        QueryWrapper<SysConfigPO> queryWrapper = SearchUtils.parseWhereSql(conditionList);
        SysConfigPO sysConfigPO = sysConfigDAO.selectOne(queryWrapper);
        if (null == sysConfigPO) {
            return null;
        }
        BeanUtils.copyProperties(sysConfigPO, sysConfigDTO);
        return sysConfigDTO;
    }

    @Override
    public List<SysConfigDTO> list(SysConfigDTO sysConfigDTO) throws IllegalAccessException {
        // 添加查询条件
        List<Condition> conditionList = ConditionUtils.add(sysConfigDTO);
        // 拼接查询条件
        QueryWrapper<SysConfigPO> queryWrapper = SearchUtils.parseWhereSql(conditionList);
        return JsonUtils.copyList(sysConfigDAO.selectList(queryWrapper), SysConfigDTO.class);
    }

    @Override
    public PageDataInfo<SysConfigDTO> listPage(SysConfigDTO sysConfigDTO) throws IllegalAccessException {
        // 添加查询条件
        List<Condition> conditionList = ConditionUtils.add(sysConfigDTO);
        // 拼接查询条件
        QueryWrapper<SysConfigPO> queryWrapper = SearchUtils.parseWhereSql(conditionList);
        List<SysConfigPO> list = sysConfigDAO.selectList(queryWrapper);
        PageInfo<SysConfigPO> pageInfo = new PageInfo<>(list);
        PageDataInfo<SysConfigDTO> pageDataInfo = new PageDataInfo<>();
        pageDataInfo.setData(JsonUtils.copyList(list, SysConfigDTO.class));
        pageDataInfo.setTotal(pageInfo.getTotal());
        return pageDataInfo;
    }

    @Override
    public String selectConfigByKey(String configKey) throws IllegalAccessException {
        String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey)));
        if (StringUtils.isNotEmpty(configValue)) {
            return configValue;
        }
        SysConfigDTO config = new SysConfigDTO();
        config.setConfigKey(configKey);
        SysConfigDTO retConfig = get(config);
        if (StringUtils.isNotNull(retConfig)) {
            redisCache.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue());
            return retConfig.getConfigValue();
        }
        return StringUtils.EMPTY;
    }

    @Override
    public Boolean selectCaptchaEnabled() throws IllegalAccessException {
        String captchaEnabled = selectConfigByKey("sys.account.captchaEnabled");
        if (StringUtils.isEmpty(captchaEnabled)) {
            return false;
        }
        return Convert.toBool(captchaEnabled);
    }

    /**
     * 加载参数缓存数据
     */
    @Override
    public void loadingConfigCache() throws IllegalAccessException {
        List<SysConfigDTO> configsList = list(new SysConfigDTO());
        for (SysConfigDTO config : configsList)
        {
            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
        }
    }

    /**
     * 清空参数缓存数据
     */
    @Override
    public void clearConfigCache()
    {
        Collection<String> keys = redisCache.keys(String.format(CacheConstants.SYS_CONFIG_KEY) + "*");
        redisCache.deleteObject(keys);
    }

    @Override
    public void resetConfigCache() throws IllegalAccessException {
        clearConfigCache();
        loadingConfigCache();
    }

    @Override
    public String checkConfigKeyUnique(SysConfigDTO sysConfigDTO) throws IllegalAccessException {
        String configId = StringUtils.isNull(sysConfigDTO.getConfigId()) ? "-1" : sysConfigDTO.getConfigId();
        SysConfigDTO info = get(SysConfigDTO.builder().configKey(sysConfigDTO.getConfigKey()).build());
        if (StringUtils.isNotNull(info) && !info.getConfigId().equals(configId)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
}
